package pl.com.sthaether.mc.components.table.filterable;

import javafx.collections.FXCollections;
import javafx.collections.transformation.FilteredList;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;

import java.util.ArrayList;
import java.util.List;
// inspiration - http://code.makery.ch/blog/javafx-8-tableview-sorting-filtering/
public class MCFilterableTable<T> extends VBox {
    private TextField searchField;
    private TableView<MCFilterableTableItem<T>> table;

    public MCFilterableTable(List<MCFilterableTableItem<T>> itemsList, boolean withIcon, boolean withDescription) {
        init(withIcon, withDescription);
        setTableData(itemsList);
    }

    public MCFilterableTable(boolean withIcon, boolean withDescription) {
        init(withIcon, withDescription);
        setTableData(new ArrayList<MCFilterableTableItem<T>>());
    }

    private void init(boolean withIcon, boolean withDescription) {
        searchField = new TextField();
        table = createTable(withIcon, withDescription);
        table.prefHeightProperty().bind(heightProperty());
        this.getChildren().addAll(searchField, table);
    }

    public void setTableData(List<MCFilterableTableItem<T>> itemsList) {
        FilteredList<MCFilterableTableItem<T>> filteredData = new FilteredList<>(FXCollections.observableList(itemsList), t -> true);

        searchField.textProperty().addListener((observable, oldValue, newValue) -> filteredData.setPredicate(tool -> {
            if (newValue == null || newValue.isEmpty()) {
                return true;
            }
            return tool.matchesText(newValue);
        }));
        table.setItems(filteredData);
    }

    public void addTableItem(MCFilterableTableItem<T> item) {
        table.getItems().add(item);
    }

    public void removeTableItem(MCFilterableTableItem<T> item) {
        table.getItems().remove(item);
    }

    private TableView<MCFilterableTableItem<T>> createTable(boolean withIcon, boolean withDescription) {
        TableView<MCFilterableTableItem<T>> table = new TableView<>();

        if (withIcon) {
            TableColumn<MCFilterableTableItem<T>, Image> columnIcon = new TableColumn<>("Icon");
            columnIcon.setMinWidth(40);
            columnIcon.setCellFactory((param) -> new TableCell<MCFilterableTableItem<T>, Image>() {
                ImageView image;

                {
                    image = new ImageView();
                    setGraphic(image);
                }

                @Override
                protected void updateItem(Image item, boolean empty) {
                    image.setImage(item);
                }
            });
            table.getColumns().add(columnIcon);
        }
        TableColumn<MCFilterableTableItem<T>, String> columnName = new TableColumn<>("Name");
        columnName.setMinWidth(100);
        columnName.setCellValueFactory(cellData -> cellData.getValue().getNameProperty());
        table.getColumns().add(columnName);
        if (withDescription) {
            TableColumn<MCFilterableTableItem<T>, String> columnType = new TableColumn<>("Description");
            columnType.setMinWidth(120);
            columnType.setCellValueFactory(cellData -> cellData.getValue().getDescriptionProperty());
            table.getColumns().add(columnType);
        }

        return table;
    }

}
